home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / netmail / rnr214.zip / RNRIO.PAS < prev    next >
Pascal/Delphi Source File  |  1996-01-30  |  15KB  |  808 lines

  1. unit rnrio;
  2.  
  3. {
  4.  
  5. rnrio.pas - nonconsole input/output routines
  6.  
  7. assumes a fossil (if the nonconsole routines will ever be used)
  8.  
  9. requires:
  10.  
  11. uses dos,crt,rnrglob,rnrmous ( , and possibly rnrtime ) ;
  12.  
  13. shortcomings:
  14.  
  15. minimal ansi/vt100 hard-coded in
  16.  
  17. }
  18.  
  19. {$I rnr-def.pas}
  20.  
  21. interface
  22.  
  23. uses dos,crt,genericf,rnrglob,rnrconf,rnrmous
  24.  
  25. {$ifdef timeout}
  26.  
  27. ,rnrtime
  28.  
  29. {$endif}
  30.  
  31. {$ifdef mouse}
  32.  
  33. ,mouse
  34.  
  35. {$endif}
  36.  
  37. ;
  38.  
  39. const
  40.   yespreserve=true;
  41.   nopreserve=false;
  42.   endkeysnospace=  #13#27#10;       { CR, ESC, LF             }
  43.   endkeyswithspace=#13#27#10' '#9;  { CR, ESC, LF, SPACE, TAB }
  44.  
  45. procedure xwrites(s: string);
  46. procedure xwritesw(s: string; w: integer);
  47. procedure xwritei(i: integer);
  48. procedure xwriteiw(i,w: integer);
  49. procedure xwritess(s1,s2: string);
  50. procedure xwritesss(s1,s2,s3: string);
  51. procedure xwritessss(s1,s2,s3,s4: string);
  52. procedure xwritesis(s1: string; i2: integer; s3: string);
  53. procedure xwritessis(s1,s2: string; i3: integer; s4: string);
  54. procedure xwriteln;
  55. procedure xwritelns(s: string);
  56. procedure xwritelnss(s1,s2: string);
  57. procedure xwritelnsss(s1,s2,s3: string);
  58. procedure xwritelnssss(s1,s2,s3,s4: string);
  59. procedure xwritelnsi(s1: string; i2: integer);
  60. {
  61. procedure xwritelnsssisis(s1,s2,s3: string; i4: integer; s5: string;
  62.  i6: integer; s7: string);
  63. }
  64. procedure xgotoxy(x,y: integer);
  65. procedure writexy(x,y: integer; s: string);
  66. procedure xclreol;
  67. procedure xclreolxy(x,y: integer);
  68. procedure xclrscr;
  69. function xkeypressed: boolean;
  70. function xreadkeyextended(forcecolumn: integer; forcerow: integer;
  71.  beginrow, endrow: integer): char;
  72. function xreadkey: char;
  73. procedure xreadlnseh(var s: string; maxlen: integer; keepcurrent: boolean;
  74.  endlist: string; readlnhistoryp: readlnhistorypt);
  75. procedure xreadlnse(var s: string; maxlen: integer; keepcurrent: boolean;
  76.  endlist: string);
  77. procedure xreadlns(var s: string; maxlen: integer; keepcurrent: boolean);
  78.  
  79. procedure xsetcolor(color: byte);
  80. procedure xhighvideo;
  81. procedure xlowvideo;
  82.  
  83. {
  84. procedure xquotevideo;
  85. procedure xalternatevideo;
  86. procedure xdatevideo;
  87. }
  88.  
  89. procedure xwritehighlights(s: string);
  90. procedure hwritexy(x,y: integer; s: string);
  91.  
  92. implementation
  93.  
  94. procedure noncwritec(c: char);
  95.  
  96. var
  97.   regs: registers;
  98.  
  99. begin
  100.   regs.dx := port;
  101.   regs.ah := 1;
  102.   regs.al := ord(c);
  103.   intr($14,regs);
  104. end;
  105.  
  106. function noncreadc: char;
  107.  
  108. var
  109.   regs: registers;
  110.  
  111. begin
  112.   regs.dx := port;
  113.   regs.ah := 2;
  114.   intr($14,regs);
  115.   noncreadc := chr(regs.al);
  116. end;
  117.  
  118. function noncinready: boolean;
  119.  
  120. var
  121.   regs: registers;
  122.  
  123. begin
  124.   regs.dx := port;
  125.   regs.ah := 3;
  126.   intr($14,regs);
  127.   noncinready := odd(regs.ah);
  128. end;
  129.  
  130. procedure xwrites;
  131.  
  132. var
  133.   i: integer;
  134.  
  135. begin
  136.   if console then
  137.     begin
  138.       mousehide;
  139.       write(s);
  140.       mouseshow;
  141.     end
  142.   else
  143.     begin
  144.       for i := 1 to length(s) do
  145.         noncwritec(s[i]);
  146.       if shadow>0 then
  147.         begin
  148.           write(s);
  149.           delay(shadow);
  150.         end;
  151.     end;
  152. end;
  153.  
  154. procedure xwritesw;
  155.  
  156. var
  157.   paddeds: string;
  158.   i: integer;
  159.  
  160. begin
  161.   paddeds := s;
  162.   for i := 1 to w-length(s) do
  163.     paddeds := ' '+paddeds;
  164.   xwrites(paddeds);
  165. end;
  166.  
  167. procedure xwritei;
  168.  
  169. var
  170.   s: string;
  171.  
  172. begin
  173. {
  174.   if console then
  175.     begin
  176.       mousehide;
  177.       write(i);
  178.       mouseshow;
  179.     end
  180.   else
  181.     begin
  182. }
  183.       str(i,s);
  184.       xwrites(s);
  185. {
  186.     end;
  187. }
  188. end;
  189.  
  190. procedure xwriteiw;
  191.  
  192. var
  193.   s: string;
  194.  
  195. begin
  196. {
  197.   if console then
  198.     begin
  199.       mousehide;
  200.       write(i:w);
  201.       mouseshow;
  202.     end
  203.   else
  204.     begin
  205.       str(i:w,s);
  206.       xwrites(s);
  207.     end;
  208. }
  209.   str(i,s);
  210.   xwritesw(s,w);
  211. end;
  212.  
  213. procedure xwritess;
  214.  
  215. begin
  216.   xwrites(s1);
  217.   xwrites(s2);
  218. end;
  219.  
  220. procedure xwritesss;
  221.  
  222. begin
  223.   xwrites(s1);
  224.   xwrites(s2);
  225.   xwrites(s3);
  226. end;
  227.  
  228. procedure xwritessss;
  229.  
  230. begin
  231.   xwrites(s1);
  232.   xwrites(s2);
  233.   xwrites(s3);
  234.   xwrites(s4);
  235. end;
  236.  
  237. procedure xwritesis;
  238.  
  239. begin
  240.   xwrites(s1);
  241.   xwritei(i2);
  242.   xwrites(s3);
  243. end;
  244.  
  245. procedure xwritessis;
  246.  
  247. begin
  248.   xwritess(s1,s2);
  249.   xwritei(i3);
  250.   xwrites(s4);
  251. end;
  252.  
  253. procedure xwriteln;
  254.  
  255. begin
  256.   if console then
  257.     begin
  258.       mousehide;
  259.       writeln;
  260.       mouseshow;
  261.     end
  262.   else
  263.     xwritess(chr(13),chr(10));
  264. end;
  265.  
  266. procedure xwritelns;
  267.  
  268. begin
  269.   xwrites(s);
  270.   xwriteln;
  271. end;
  272.  
  273. procedure xwritelnss;
  274.  
  275. begin
  276.   xwrites(s1);
  277.   xwrites(s2);
  278.   xwriteln;
  279. end;
  280.  
  281. procedure xwritelnsss;
  282.  
  283. begin
  284.   xwrites(s1);
  285.   xwrites(s2);
  286.   xwrites(s3);
  287.   xwriteln;
  288. end;
  289.  
  290. procedure xwritelnssss;
  291.  
  292. begin
  293.   xwrites(s1);
  294.   xwrites(s2);
  295.   xwrites(s3);
  296.   xwrites(s4);
  297.   xwriteln;
  298. end;
  299.  
  300. procedure xwritelnsi;
  301.  
  302. begin
  303.   xwrites(s1);
  304.   xwritei(i2);
  305.   xwriteln;
  306. end;
  307.  
  308. {
  309. procedure xwritelnsssisis;
  310.  
  311. begin
  312.   xwritesss(s1,s2,s3);
  313.   xwritei(i4);
  314.   xwrites(s5);
  315.   xwritei(i6);
  316.   xwritelns(s7);
  317. end;
  318. }
  319.  
  320. procedure xgotoxy;
  321.  
  322. begin
  323.   if console then
  324.     begin
  325.       mousehide;
  326.       gotoxy(x,y);
  327.       mouseshow;
  328.     end
  329.   else
  330.     begin
  331.       xwritess(esc,'[');
  332.       xwritei(y);
  333.       xwrites(';');
  334.       xwritei(x);
  335.       xwrites('f');
  336.     end;
  337. end;
  338.  
  339. procedure writexy;
  340.  
  341. begin
  342.   xgotoxy(x,y);
  343.   xwrites(s);
  344. end;
  345.  
  346. procedure xclreol;
  347.  
  348. begin
  349.   if console then
  350.     begin
  351.       mousehide;
  352.       clreol;
  353.       mouseshow;
  354.     end
  355.   else
  356.     xwritess(esc,'[0K');
  357. end;
  358.  
  359. procedure xclreolxy;
  360.  
  361. begin
  362.   xgotoxy(x,y);
  363.   xclreol;
  364. end;
  365.  
  366. procedure xclrscr;
  367.  
  368. begin
  369.   if console then
  370.     begin
  371.       mousehide;
  372.       clrscr;
  373.       mouseshow;
  374.     end
  375.   else
  376.     begin
  377.       xwritess(esc,'[2J');
  378.       xgotoxy(1,1);
  379.     end;
  380. end;
  381.  
  382. function xkeypressed;
  383.  
  384. var
  385.   result: boolean;
  386.  
  387. {$ifdef timeout}
  388.   minnow: integer;
  389. {$endif}
  390.  
  391. begin
  392.   result := false;
  393.  
  394.   if console then
  395.     begin
  396. {$ifdef mouse}
  397.       if hasmouse then
  398.         result := keypressed or (mousevent.event<>0)
  399.       else
  400.         result := keypressed;
  401. {$else}
  402.       result := keypressed;
  403. {$endif}
  404.     end
  405.   else
  406.     begin
  407.  
  408. {check for timeout _before_ checking if a key is ready - modems can spew}
  409.  
  410. {now also checks for trusted users!  but not on the console}
  411.  
  412. {$ifdef timeout}
  413.  
  414.       minnow := mitoday;
  415.       if minnow<minstart then
  416.         inc(minnow,24*60);
  417.       if (minutestorun>=0) and (minnow-minstart>=minutestorun) then
  418.         begin
  419. {$ifdef timeoutreturnscr}
  420.           didtimeout := true;
  421.           result := true;
  422. {$else}
  423.           xwriteln;
  424.           xwritelns('time up');
  425.           xwriteln;
  426.           halt(2);
  427. {$endif}
  428.         end;
  429.  
  430.       if minnow<minlastinput then
  431.         inc(minnow,24*60);
  432.  
  433.       if minnow-minlastinput>idleminutes then
  434.         begin
  435.           xwriteln;
  436.           xwritelns('idle timeout');
  437.           xwriteln;
  438.           halt(2);
  439.         end;
  440.  
  441. {$endif}
  442.  
  443. {$ifdef mouse}
  444.       if hasmouse then
  445.         result := noncinready or keypressed or (mousevent.event<>0)
  446.       else
  447.         result := noncinready or keypressed;
  448. {$else}
  449.       result := noncinready or keypressed;
  450. {$endif}
  451.  
  452.     end;
  453.  
  454. {$ifdef timeout}
  455.   if result then
  456.     minlastinput := mitoday;
  457. {$endif}
  458.  
  459.   xkeypressed := result;
  460. end;
  461.  
  462. function xreadkeyextended;
  463.  
  464. var
  465.   result: char;
  466.  
  467. {$ifdef mouse}
  468.   regs: registers;
  469.   wasx, wasy: byte;
  470.   newx, newy: byte;
  471. {$endif}
  472.  
  473. begin
  474.   if console then
  475.     begin
  476.  
  477. { ignore function keys, alt keys, numeric pad keys - translate to ' ' }
  478.  
  479.       repeat
  480.  
  481. {$ifdef mouse}
  482.  
  483.         repeat
  484.         { nothing - we're on the console }
  485.         until xkeypressed;
  486.  
  487.         if keypressed then
  488.           begin
  489.             result := readkey;
  490.           end
  491.         else
  492.           begin
  493.             wasx := wherex;
  494.             wasy := wherey;
  495.  
  496.             newx := 1+(mousevent.horiz div 8);
  497.             newy := 1+(mousevent.vert div 8);
  498.  
  499.             if (newy>=beginrow) and (newy<=endrow) then
  500.               newx := 1;
  501.  
  502.             if forcecolumn<>0 then
  503.               newx := forcecolumn;
  504.             if forcerow<>0 then
  505.               newy := forcerow;
  506.  
  507.             gotoxy(newx,newy);
  508.  
  509. {read character from screen}
  510.             regs.ah := 8;
  511.             regs.bh := 0;
  512.             intr($10,regs);
  513.  
  514.             result := chr(regs.al);
  515.  
  516.             gotoxy(wasx,wasy);
  517.             mousevent.event := 0;
  518.           end;
  519.  
  520. {$else}
  521.  
  522.         result := readkey;
  523.  
  524. {$endif}
  525.  
  526.         if (result=#0) and keypressed then
  527.           begin
  528.             result := readkey;
  529.  
  530. { change these extended keys: }
  531.  
  532. {    2nd Char key pressed    code returned       }
  533. {    -------- -----------    -------------       }
  534. {    I  73    PgUp           <                   }
  535. {    Q  81    PgDn           space (or >)        }
  536. {    G  71    Home           ^A (or ^)           }
  537. {    O  79    End            ^E (or $)           }
  538. {    ;  59    F1             ?                   }
  539. {    K  75    left arrow     ^B (or backspace)   }
  540. {    M  77    right arrow    ^F                  }
  541. {    H  72    up arrow       ^P                  }
  542. {    P  80    down arrow     ^N                  }
  543. {    S  83    del            ^D                  }
  544. {    $  36    alt-J          !                   }
  545.  
  546.             if result='I' then
  547.               result := '<'
  548.             else if result='Q' then
  549. {$ifdef pgdnbecomesgt}
  550.               result := '>'
  551. {$else}
  552.               result := ' '
  553. {$endif}
  554.             else if result='G' then
  555. {$ifdef homebecomescarat}
  556.               result := '^'
  557. {$else}
  558.               result := ^A
  559. {$endif}
  560.             else if result='O' then
  561. {$ifdef endbecomesdollar}
  562.               result := '$'
  563. {$else}
  564.               result := ^E
  565. {$endif}
  566.             else if result=';' then
  567.               result := '?'
  568.             else if result='K' then
  569. {$ifdef leftbecomesbackspace}
  570.               result := #8
  571. {$else}
  572.               result := ^B
  573. {$endif}
  574.             else if result='M' then
  575.               result := ^F
  576.             else if result='H' then
  577.               result := ^P
  578.             else if result='P' then
  579.               result := ^N
  580.             else if result='S' then
  581.               result := ^D
  582.             else if result='$' then
  583.               result := '!'
  584.             else
  585.  
  586. { ignore other extended keys }
  587.  
  588.               result := #0;
  589.  
  590.           end;
  591.  
  592.       until result<>#0;
  593.     end
  594.   else
  595.     begin
  596.       while not xkeypressed do
  597.         ;
  598.       if keypressed then
  599.         result := readkey
  600.       else
  601.         result := noncreadc;
  602.     end;
  603.   xreadkeyextended := mainmap[result];
  604. end;
  605.  
  606. function xreadkey;
  607.  
  608. begin
  609.   xreadkey := xreadkeyextended(0,0,0,0);
  610. end;
  611.  
  612. procedure xreadlnseh;  {readln, can end with some non-RETURN keys, history}
  613.  
  614. {acceptable lists are RETURN plus some of LF, SPACE, TAB, ESC}
  615.  
  616. {readlnhistoryp can be nil to indicate no history}
  617.  
  618. var
  619.   result: string;
  620.   done: boolean;
  621.  
  622.   len: integer;        {the length of the string}
  623.   position: integer;   {the position in the string, or len+1}
  624.   onekey: char;        {one key from the keyboard}
  625.   tempint: integer;
  626.  
  627. begin
  628.   if keepcurrent then
  629.     result := s
  630.   else
  631.     result := '';
  632.  
  633.   len := length(result);
  634.   xwrites(result);
  635.   position := len+1;  {+1 since we're appending at the end}
  636.  
  637.   done := false;
  638.  
  639.   while not done do
  640.     begin
  641.       onekey := xreadkey;
  642.       if (onekey=#127) or (onekey=#8) then  {backspace}
  643.         begin
  644.           if position>1 then
  645.             begin
  646.               dec(position);
  647.               dec(len);
  648.               if len=0 then
  649.                 result := ''
  650.               else
  651.                 result :=
  652.                  copy(result,1,position-1)+copy(result,position+1,255);
  653.  
  654.               xwrites(^H);
  655.               xclreol;
  656.               xwrites(copy(result,position,255));
  657.               for tempint := 0 to (len-position) do
  658.                 xwrites(^H);
  659.             end;
  660.         end
  661.       else if onekey=^D then  {delete}
  662.         begin
  663.           if position<=len then
  664.             begin
  665.               dec(len);
  666.               if len=0 then
  667.                 result := ''
  668.               else
  669.                 result :=
  670.                  copy(result,1,position-1)+copy(result,position+1,255);
  671.  
  672.               xclreol;
  673.               xwrites(copy(result,position,255));
  674.               for tempint := 0 to (len-position) do
  675.                 xwrites(^H);
  676.             end;
  677.         end
  678.       else if onekey=^B then  {back a character}
  679.         begin
  680.           if position>1 then
  681.             begin
  682.               xwrites(#8);
  683.               dec(position);
  684.             end;
  685.         end
  686.       else if onekey=^F then  {forward a character}
  687.         begin
  688.           if position<len+1 then
  689.             begin
  690.               if position<=len then
  691.                 xwrites(copy(result,position,1));
  692.               inc(position);
  693.             end;
  694.         end
  695.       else if onekey=^A then  {beginning}
  696.         begin
  697.           for tempint := position-1 downto 1 do
  698.             begin
  699.               xwrites(#8);
  700.               dec(position);
  701.             end;
  702.         end
  703.       else if onekey=^E then  {end}
  704.         begin
  705.           for tempint := position+1 to len+1 do
  706.             begin
  707.               xwrites(copy(result,position,1));
  708.               inc(position);
  709.             end;
  710.         end
  711.       else if pos(onekey,endlist)<>0 then  {finished}
  712.         begin
  713. {$ifdef xwritelnafterxreadln}
  714.           xwriteln;
  715. {$endif}
  716.           done := true;
  717.         end
  718.       else if onekey=^U then  {erase it all}
  719.         begin
  720.           for tempint := 1 to position-1 do
  721.             xwrites(^H);
  722.           xclreol;
  723.           result := '';
  724.           len := 0;
  725.           position := 1;
  726.         end
  727.       else if (ord(onekey)>=32) and (eightbitclean or (ord(onekey)<128))
  728.        and (len<maxlen) then  {insert a character}
  729.         begin
  730.           inc(len);
  731.           result := copy(result,1,position-1)+onekey+copy(result,position,255);
  732.  
  733.           xwrites(copy(result,position,255));
  734.           inc(position);
  735.           for tempint := 0 to (len-position) do
  736.             xwrites(^H);
  737.         end;
  738.     end;
  739.  
  740.   s := result;
  741. end;
  742.  
  743. procedure xreadlnse;
  744.  
  745. {acceptable lists are RETURN plus some of LF, SPACE, TAB, ESC}
  746.  
  747. begin
  748.   xreadlnseh(s,maxlen,keepcurrent,endlist,nil);
  749. end;
  750.  
  751. procedure xreadlns;
  752.  
  753. begin
  754.   xreadlnse(s,maxlen,keepcurrent,endkeysnospace);
  755. end;
  756.  
  757. procedure xsetcolor;
  758.  
  759. {color is 0-15, background is 0-7}
  760.  
  761. begin
  762.   if console then
  763.     begin
  764.       textcolor(color and $f);
  765.       textbackground(color shr 4);
  766.     end
  767.   else if color=highcolor then
  768.     xwritess(esc,'[7m')
  769.   else
  770.     xwritess(esc,'[m');
  771. end;
  772.  
  773. procedure xhighvideo;
  774.  
  775. begin
  776.   xsetcolor(highcolor);
  777. end;
  778.  
  779. procedure xlowvideo;
  780.  
  781. begin
  782.   xsetcolor(lowcolor);
  783. end;
  784.  
  785. procedure xwritehighlights;
  786.  
  787. var
  788.   i: integer;
  789.  
  790. begin
  791.   for i := 1 to length(s) do
  792.     if s[i]='{' then
  793.       xhighvideo
  794.     else if s[i]='}' then
  795.       xlowvideo
  796.     else
  797.       xwrites(s[i]);
  798. end;
  799.  
  800. procedure hwritexy;
  801.  
  802. begin
  803.   xgotoxy(x,y);
  804.   xwritehighlights(s);
  805. end;
  806.  
  807. end.
  808.